﻿using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace WpfSessionTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            IntPtr hwnd = new WindowInteropHelper(this).Handle;

            string versionStr = RuntimeEnvironment.GetSystemVersion();

            if (versionStr.StartsWith("v2.0"))
            {
                if (!WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
                }
            }

            HwndSource.FromHwnd(hwnd).AddHook(new HwndSourceHook(HwndProc));
        }

        #region WM Message
        const int WM_WTSSESSION_CHANGE = 0x02B1;
        const int WM_CREATE = 0x0001, WM_MOVE = 0x0003;
        const int WM_POWERBROADCAST = 0x0218;
        #endregion

        #region PBT
        const int PBT_APMSUSPEND = 0x0004;
        const int PBT_APMQUERYSUSPEND = 0x0000;
        const int PBT_APMQUERYSUSPENDFAILED = 0x0002;
        const int PBT_APMRESUMECRITICAL = 0x0006;
        const int PBT_APMRESUMESUSPEND = 0x0007;
        const int PBT_APMPOWERSTATUSCHANGE = 0x000A;
        const int PBT_POWERSETTINGCHANGE = 0x8013;
        #endregion

        #region WTS
        const int NOTIFY_FOR_THIS_SESSION = 0;
        const int WTS_CONSOLE_CONNECT = 0x1;
        const int WTS_CONSOLE_DISCONNECT = 0x2;
        const int WTS_REMOTE_CONNECT = 0x3;
        const int WTS_REMOTE_DISCONNECT = 0x4;
        const int WTS_SESSION_LOGON = 0x5;
        const int WTS_SESSION_LOGOFF = 0x6;
        const int WTS_SESSION_LOCK = 0x7;
        const int WTS_SESSION_UNLOCK = 0x8;
        const int WTS_SESSION_REMOTE_CONTROL = 0x9;
        #endregion



        IntPtr HwndProc(IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (message)
            {
                case WM_WTSSESSION_CHANGE:
                    {
                        LogHelper.WriteWithTime("WM_WTSSESSION_CHANGE");
                        SessionChanged((int)wParam, lParam);
                        break;
                    }
                case WM_POWERBROADCAST:
                    {
                        LogHelper.WriteWithTime("WM_POWERBROADCAST");
                        PowerBoardcast((int)wParam, lParam);
                        break;
                    }
            }
            return IntPtr.Zero;
        }

        void SessionChanged(int wParam, IntPtr lParam)
        {
            switch (wParam)
            {
                case WTS_SESSION_LOCK:
                    LogHelper.WriteWithTime("Session Lock");
                    break;
                case WTS_SESSION_UNLOCK:
                    LogHelper.WriteWithTime("Session UnLock");
                    break;
                case WTS_SESSION_LOGON:
                    LogHelper.WriteWithTime("Log on");
                    break;
                case WTS_SESSION_LOGOFF:
                    LogHelper.WriteWithTime("Log Off");
                    break;
                case WTS_CONSOLE_CONNECT:
                    LogHelper.WriteWithTime("WTS_CONSOLE_CONNECT");
                    break;
                case WTS_CONSOLE_DISCONNECT:
                    LogHelper.WriteWithTime("WTS_CONSOLE_DISCONNECT");
                    break;
                default:
                    LogHelper.WriteWithTime("SessionChanged Code:{0}", wParam);
                    break;
            }
        }

        void PowerBoardcast(int wParam, IntPtr lParam)
        {
            switch (wParam)
            {
                case PBT_APMSUSPEND: { LogHelper.WriteWithTime("PBT_APMSUSPEND"); break; }
                case PBT_APMQUERYSUSPEND: LogHelper.WriteWithTime("PBT_APMQUERYSUSPEND"); break;
                case PBT_APMQUERYSUSPENDFAILED: LogHelper.WriteWithTime("PBT_APMQUERYSUSPENDFAILED"); break;
                case PBT_APMRESUMECRITICAL: LogHelper.WriteWithTime("PBT_APMRESUMECRITICAL"); break;
                case PBT_APMRESUMESUSPEND: LogHelper.WriteWithTime("PBT_APMRESUMESUSPEND"); break;
                default:
                    LogHelper.WriteWithTime("PowerBoardcast code:{0}", wParam); break;
            }
        }

        #region DllImport Method
        [DllImport("WtsApi32.dll")]
        static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);
        [DllImport("WtsApi32.dll")]
        static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
        #endregion


    }


}
